home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / technote / tchntstc.sit / Technical Notes Stack 3.2.1 / Technical Notes Stack 3.2.1 / card_46873.txt < prev    next >
Encoding:
Text File  |  1990-01-08  |  10.1 KB  |  238 lines

  1. -- card: 46873 from stack: in.1
  2. -- bmap block id: 0
  3. -- flags: 0000
  4. -- background id: 2711
  5. -- name: 154 Displaying Large PICT Files 
  6.  
  7.  
  8. -- part contents for background part 9
  9. ----- text -----
  10. #154: Displaying Large PICT Files 
  11.  
  12. See also:     QuickDraw
  13.               Technical Note #21 ΓÇö Internal Picture Format
  14.               Technical Note #35 ΓÇö DrawPicture Problem
  15.               Technical Note #88 - Signals
  16.  
  17. Written by:    Rick Blair    July 1, 1987
  18. Updated:                     March 1, 1988
  19. _______________________________________________________________________________
  20.  
  21. Now that we have scanners and other massive-picture producing types of applications, there is a need to address the problem of how to display a PICT format object that is bigger than a current PICT resource is allowed to be. Note that this technique applies equally well to version 1 and version 2 
  22. (word-opcode) pictures as produced by the Macintosh II.
  23. _______________________________________________________________________________
  24.  
  25.  
  26. Future Compatibility
  27.  
  28. Think of the handle returned by a GetResource('PICT',ID) as a ΓÇ£handleΓÇ¥ in the more general sense of being an abstract ΓÇ£tagΓÇ¥ΓÇösomething that the ROM routines can use to draw the picture with. DonΓÇÖt assume that the entire picture has been read into memory or that you can directly read any bytes beyond the basic Picture record structure (picSize followed by picFrame). Someday we may provide a mechanism for the resource to be disk- instead of memory-based. The QuickDraw bottleneck procedures will know how to get data from and put data into the pictures in any case.
  29.  
  30.  
  31. Spooling from a PICT file
  32.  
  33. In order to display pictures of arbitrary size, your application should be able to import a QuickDraw picture from a file of type PICT. This is the file produced by a ΓÇ£Save asΓǪΓÇ¥ from MacDraw with the PICT option selected.
  34.  
  35. What follows is a small program fragment that demonstrates how to spool in a picture from [the data fork of] a PICT file. The picture can be larger than the historical 32K resource size. See technical note #88 if you are unfamiliar with the Signal mechanism. We assume that a CatchSignals has been done before GetandDrawPICTFile is called.
  36.  
  37.  
  38. MPW Pascal Example
  39.  
  40.     {the following variable must be at the top level}
  41.  
  42.     VAR
  43.        globalRef   : INTEGER;      {refNum of the file to read from}
  44.  
  45.     {the following procedure must be at the top level}
  46.  
  47.     PROCEDURE GetPICTData(dataPtr: Ptr; byteCount: INTEGER);
  48.     {replacement for the QuickDraw bottleneck routine}
  49.  
  50.        VAR
  51.           err         : OSErr;
  52.           longCount   : LONGINT;
  53.  
  54.        BEGIN
  55.           longCount := byteCount;
  56.           err := FSRead(globalRef,longCount,dataPtr);
  57.           {can't check for an error because we don't know how to handle it}
  58.        END;
  59.  
  60.     CONST
  61.        abortPICT    = 128;         {error code if DrawPicture aborted}
  62.  
  63.     PROCEDURE GetDrawPICTFile;     {read in a PICT FILE selected by the user}
  64.  
  65.        VAR
  66.           wher        : Point;     {where to display dialog}
  67.           reply       : SFReply;   {reply record}
  68.           myFileTypes : SFTypeList; {more Standard FILE goodies}
  69.           numFileTypes: INTEGER;
  70.  
  71.           savedProcs  : QDProcsPtr;
  72.           myProcs     : QDProcs;   {use CQDProcs for a color window}
  73.  
  74.           myPicture   : PicHandle; {we need a picture handle for DrawPicture}
  75.           longCount   : LONGINT;
  76.           myEOF       : LONGINT;
  77.           myFilePos   : LONGINT;
  78.  
  79.        BEGIN
  80.           wher.h := 20;
  81.           wher.v := 20;
  82.           numFileTypes := 1;       {display PICT files}
  83.           myFileTypes[0] := 'PICT';
  84.           SFGetFile(wher,'',NIL,numFileTypes,myFileTypes,NIL,reply);
  85.  
  86.           IF reply.good THEN BEGIN
  87.              SetStdProcs(myProcs); {use SetStdCProcs for a CGrafPort}
  88.              myProcs.getPicProc := @GetPICTData;
  89.              savedProcs := thePort^.grafProcs; {set the grafProcs to ours}
  90.              thePort^.grafProcs := @myProcs;
  91.  
  92.              myPicture := PicHandle(NewHandle(SizeOf(myPicture)));
  93.  
  94.              Signal(FSOpen(reply.fname,reply.vRefNum,globalRef));
  95.              Signal(GetEOF(globalRef,myEOF)); {get EOF for later check}
  96.              Signal(SetFPos(globalRef,fsFromStart,512)); {skip header}
  97.  
  98.              {read in the (obsolete) size word and the picFrame}
  99.              longCount := SizeOf(myPicture);
  100.              Signal(FSRead(globalRef,longCount,Ptr(myPicture^)));
  101.  
  102.              DrawPicture(myPicture,myPicture^^.picFrame); {draw the picture}
  103.  
  104.              Signal(GetFPos(globalRef,filePos)); {get position for check}
  105.              Signal(FSClose(globalRef));
  106.  
  107.              DisposHandle(Handle(myPicture));
  108.  
  109.              thePort^.grafProcs := savedProcs; {restore the procs}
  110.  
  111.              {Check for errors. If there wasn't enough room,}
  112.              {DrawPicture will abort; the FILE position mark}
  113.              {won't be at the end of the FILE.}
  114.              IF filePos <> myEOF THEN Signal(abortPICT);
  115.           END; {IF reply.good}
  116.        END; {GetDrawPICTFile}
  117.  
  118.  
  119. MPW C Example
  120.  
  121. /*replacement for the QuickDraw bottleneck routine*/
  122. pascal void GetPICTData(dataPtr,byteCount)
  123. Ptr            dataPtr; 
  124. short            byteCount;
  125.  
  126.  
  127. { /* GetPICTData */
  128.     OSErr            err;
  129.     long            longCount;
  130.  
  131.     longCount = byteCount;
  132.     err = FSRead(globalRef,&longCount,dataPtr);
  133.     /*can't check for an error because we don't know how to handle it*/
  134. } /* GetPICTData */
  135.  
  136. /*error code if DrawPicture aborted*/
  137. #define       abortPICT     128         
  138.  
  139. OSErr GetDrawPICTFile()        /*read in a PICT FILE selected by the user*/
  140.  
  141. {    /* GetDrawPICTFile */   
  142.  
  143.           Point            wher;     /*where to display dialog*/
  144.           SFReply        reply;      /*reply record*/
  145.           SFTypeList        myFileTypes;/*more Standard FILE goodies*/
  146.           short            numFileTypes;
  147.         OSErr            err;
  148.           QDProcsPtr        savedProcs;
  149.           QDProcs        myProcs;/*use CQDProcs for a color window*/
  150.           PicHandle        myPicture;
  151.                     /*we need a picture handle for DrawPicture*/
  152.           long            longCount,myEOF,filePos;
  153.  
  154.           wher.h = 20;
  155.           wher.v = 20;
  156.           numFileTypes = 1;                  /*display PICT files*/
  157.           myFileTypes[0] = 'PICT';
  158.           SFGetFile(wher,'',nil,numFileTypes,myFileTypes,nil,&reply);
  159.  
  160.           if (reply.good)  
  161.         {
  162.             SetStdProcs(&myProcs);
  163.             /*use SetStdCProcs for a CGrafPort*/
  164.                  myProcs.getPicProc = GetPICTData;
  165.                  savedProcs = (*qd.thePort).grafProcs;
  166.                                        /*set the grafProcs to ours*/
  167.                  (*qd.thePort).grafProcs = &myProcs;
  168.  
  169.                  myPicture = (PicHandle)NewHandle(sizeof(Picture));
  170.  
  171.             err = FSOpen(&reply.fName,reply.vRefNum,&globalRef);
  172.             if (err != noErr) return err;
  173.  
  174.               err = GetEOF(globalRef,&myEOF);
  175.             /*get EOF for later check*/
  176.             if (err != noErr) return err;
  177.  
  178.             err = SetFPos(globalRef,fsFromStart,512);/*skip header*/
  179.                  if (err != noErr) return err;
  180.  
  181.                  /*read in the (obsolete) size word and the picFrame*/
  182.                  longCount = sizeof(Picture);
  183.                  err = FSRead(globalRef,&longCount,(Ptr)*myPicture);
  184.                  if (err != noErr) return err;
  185.  
  186.                  DrawPicture(myPicture,&(**myPicture).picFrame); /*draw the picture*/
  187.  
  188.             err = GetFPos(globalRef,&filePos);/*get position for check*/
  189.                  if (err != noErr) return err;
  190.                  err = FSClose(globalRef);
  191.                  if (err != noErr) return err;
  192.  
  193.                  DisposHandle((Handle)myPicture);
  194.  
  195.                  (*qd.thePort).grafProcs = savedProcs;/*restore the procs*/
  196.  
  197.                  /*Check for errors. if there wasn't enough room,*/
  198.                  /*DrawPicture will abort; the FILE position mark*/
  199.                  /*won't be at the end of the FILE.*/
  200.  
  201.             if (filePos != myEOF)  return abortPICT;
  202.             else return noErr;
  203.           } /*if (reply.good) */
  204. }     /* GetDrawPICTFile */
  205.  
  206.  
  207. More on Picture Compatibility
  208.  
  209. Many applications already support PICT resources larger than 32K. The 128K ROMs (and later) allow pictures as large as memory (or spooling) will accommodate. This was made possible by having QuickDraw ignore the size word and simply read the picture until the end-of-picture opcode was reached.
  210.  
  211. For maximum safety and convenience, let QuickDraw generate and interpret your pictures.
  212.  
  213. While Apple has provided you with the data formats that allow you to read or write picture data directly, we recommend that you always let DrawPicture or OpenPicture and ClosePicture process the opcodes.
  214.  
  215. One reason to read a picture directly by scanning the opcodes would be to disassemble it to, for example, extract a Color QuickDraw pixel map to save off in a private data structure. This shouldnΓÇÖt normally be necessary.
  216.  
  217. If you do look at the picture data be sure and check the version information. You may want to put up an alert in your application that indicates to the user when a picture was created using a later version of the picture format than your application recognizes, letting them know that some elements of the picture cannot be displayed. If the version information indicates a QuickDraw picture version later than the one recognized by your application, your program should skip over the new opcodes and only attempt to parse the ones it knows.
  218.  
  219. As with reading picture data directly, it is best to use QuickDraw to create data in the PICT format. If you do need to create PICT format data directly, it is essential that you use the latest opcode specifications and that you thoroughly test the data produced on both color and black and white Macintosh machines. Contact Macintosh Developer Technical Support if you are not sure that you have the latest specifications.
  220.  
  221. Apple does not guarantee that a picture which wasnΓÇÖt produced by QuickDraw will work.
  222.  
  223.  
  224.  
  225. -- part contents for background part 2
  226. ----- text -----
  227. 154
  228.  
  229. -- part contents for background part 7
  230. ----- text -----
  231. Displaying Large PICT Files 
  232.  
  233. -- part contents for background part 113
  234. ----- text -----
  235. QuickDraw
  236. Technical Note #21
  237. Technical Note #35
  238. Technical Note #88